/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * nihongo
 * Copyright (C) Massimiliano Maniscalco 2012 <massi.neptune@yahoo.com>
 * 
nihongo is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * nihongo is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "parser_xml.h"
#include <glibmm/convert.h>
#include <iostream>



#ifdef LIBXMLCPP_EXCEPTIONS_ENABLED
void ParserXML::
on_start_document()
{
	//std::cout << "on_start_document(): inizio file" << std::endl;
}

void ParserXML::
on_end_document()
{
	commit_import_end.emit();
}

void ParserXML::
on_start_element(const Glib::ustring& name, const AttributeList& attributes)
{
	if ( codice_classe == 0 )
	{
		if ( name == Glib::ustring ( "parola" ) )
		{
			codice_classe = 1; // parola
			vox = verbum;
			verbum->cleanup();
		}
		if ( name == Glib::ustring ( "kanji" ) )
		{
			codice_classe = 2; // kanji
			vox = signum;
			signum->cleanup();
		}
		if ( name == Glib::ustring ( "esempio" ) )
		{
			codice_classe = 3; // esempio
			exemplum->cleanup();
		}
		if ( name == Glib::ustring ( "lezione" ) )
		{
			codice_classe = 4; // lezione
			lectio->cleanup();
		}
	}
	if ( codice_classe == 1 || codice_classe == 2 )
	{
		if ( name == Glib::ustring ( "contesto" ) )
			codice_elemento = 1; // contesto
		if ( name == Glib::ustring ( "testSvolti" ) )
			codice_elemento = 2; // testSvolti
		if ( name == Glib::ustring ( "indice" ) )
			codice_elemento = 3; // indice
		if ( name == Glib::ustring ( "valutazione" ) )
			codice_elemento = 4; // valutazione
		if ( name == Glib::ustring ( "data" ) )
			codice_elemento = 5; // data
		if ( name == Glib::ustring ( "ora" ) )
			codice_elemento = 6; // ora
	}
	if ( codice_classe == 1 )
	{
		if ( name == Glib::ustring ( "kotoba" ) )
			codice_elemento = 11; // kotoba
		if ( name == Glib::ustring ( "yomikata" ) )
			codice_elemento = 12; // yomikata
		if ( name == Glib::ustring ( "gaikokugo" ) )
			codice_elemento = 13; // gaikokugo
		if ( name == Glib::ustring ( "tipo" ) )
			codice_elemento = 14; // tipo
	}
	if ( codice_classe == 2 )
	{
		if ( name == Glib::ustring ( "signum" ) )
			codice_elemento = 21; // kotoba
		if ( name == Glib::ustring ( "radix" ) )
			codice_elemento = 22; // radix
		if ( name == Glib::ustring ( "onyomi" ) )
			codice_elemento = 23; // onyomi
		if ( name == Glib::ustring ( "kunyomi" ) )
			codice_elemento = 24; // kunyomi
		if ( name == Glib::ustring ( "notio" ) )
			codice_elemento = 25; // notio
		if ( name == Glib::ustring ( "signa" ) )
			codice_elemento = 26; // signa
		if ( name == Glib::ustring ( "radix_signa" ) )
			codice_elemento = 27; // radix_signa
	}
	if ( codice_classe == 3 )
	{
		if ( name == Glib::ustring ( "locutio" ) )
			codice_elemento = 31; // locutio
		if ( name == Glib::ustring ( "gaikokugo" ) )
			codice_elemento = 32; // gaikokugo
		if ( name == Glib::ustring ( "contesto" ) )
			codice_elemento = 33; // contesto
	}
	if ( codice_classe == 4 )
	{
		if ( name == Glib::ustring ( "nomen" ) )
			codice_elemento = 41; // nomen
		if ( name == Glib::ustring ( "verba" ) )
			codice_elemento = 42; // verba
		if ( name == Glib::ustring ( "notae" ) )
			codice_elemento = 43; // notae
		if ( name == Glib::ustring ( "exempla" ) )
			codice_elemento = 44; // exempla
	}

	// Check attributes:
	for(xmlpp::SaxParser::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
	{
		if ( iter->name == Glib::ustring ( "lang" ) )
		{
			commit_attribute_lang.emit ( iter->value );
		}
	}
}

void ParserXML::
on_end_element(const Glib::ustring& name )
{
	if ( name == Glib::ustring ( "parola" ) )
	{
		commit_import_parola.emit ( *verbum );
		codice_classe = 0;
	}
	if ( name == Glib::ustring ( "kanji" ) )
	{
		commit_import_kanji.emit ( *signum );
		codice_classe = 0;
	}
	if ( name == Glib::ustring ( "esempio" ) )
	{
		commit_import_esempio.emit ( *exemplum );
		codice_classe = 0;
	}
	if ( name == Glib::ustring ( "lezione" ) )
	{
		commit_import_lezione.emit ( *lectio );
		codice_classe = 0;
	}
	codice_elemento = 0;
}

void ParserXML::
on_characters(const Glib::ustring& text)
{
	try
	{
		switch ( codice_elemento )
		{
			case 1: // contesto
				if ( codice_classe == 1 || codice_classe == 2 )
					vox->set_contesto ( vox->get_contesto().append(text) );
				break;
			case 2: // testSvolti
				if ( codice_classe == 1 || codice_classe == 2 )
					vox->set_test_svolti ( text.c_str() );
				break;
			case 3: // indice
				indice = atoi ( text.c_str() );
				break;
			case 4: // valutazione
				if ( codice_classe == 1 || codice_classe == 2 )
					vox->set_valutazione ( indice, text.c_str() );
				break;
			case 5: // data
				dataOra.tm_year = atoi ( text.substr ( 0, 4 ).c_str() ) - 1900;
				dataOra.tm_mon = atoi ( text.substr ( 5, 2 ).c_str() ) - 1;
				dataOra.tm_mday = atoi ( text.substr ( 8, 2 ).c_str() );
				break;
			case 6: // ora
				dataOra.tm_hour = atoi ( text.substr ( 0, 2 ).c_str() );
				dataOra.tm_min = atoi ( text.substr ( 3, 2 ).c_str() );
				dataOra.tm_sec = atoi ( text.substr ( 6, 2 ).c_str() );
				if ( codice_classe == 1 || codice_classe == 2 )
					vox->set_data_esame ( indice, &dataOra );
				break;
			case 11: // kotoba
				verbum->set_kotoba ( verbum->get_kotoba().append(text) );
				break;
			case 12: // yomikata
				verbum->set_yomikata ( verbum->get_yomikata().append(text) );
				break;
			case 13: // gaikokugo
				verbum->set_gaikokugo ( verbum->get_gaikokugo().append(text) );
				break;
			case 14: // tipo
				verbum->set_tipo ( text.c_str() );
				break;
			case 21: // signum
				signum->set_kanji ( text );
				break;
			case 22: // radix
				signum->set_radicale ( text );
				break;
			case 23: // onyomi
				signum->set_onyomi ( signum->get_onyomi().append(text) );
				break;
			case 24: // kunyomi
				signum->set_kunyomi ( signum->get_kunyomi().append(text) );
				break;
			case 25: // notio
				signum->set_significato ( signum->get_significato().append(text) );
				break;
			case 26: // signa
				signum->set_tratti ( text.c_str() );
				break;
			case 27: // radix_signa
				signum->set_tratti_radicale ( text.c_str() );
				break;
			case 31: // locutio
				exemplum->set_bun ( exemplum->get_bun().append(text) );
				break;
			case 32: // gaikokugo
				exemplum->set_gaikokugo ( exemplum->get_gaikokugo().append(text) );
				break;
			case 33: // contesto
				exemplum->set_contesto ( exemplum->get_contesto().append(text) );
				break;
			case 41: // nomen
				lectio->set_nome ( lectio->get_nome().append(text) );
				break;
			case 42: // verba
				lectio->set_parole ( lectio->get_parole().append(text) );
				break;
			case 43: // notae
				lectio->set_kanji ( lectio->get_kanji().append(text) );
				break;
			case 44: // exempla
				lectio->set_esempi ( lectio->get_esempi().append(text) );
				break;
		}
	}
	catch(const Glib::ConvertError& ex)
	{
		std::cerr << "ParserXML::on_characters(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
	}
}

void ParserXML::
on_comment(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_comment(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_comment(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
  }
}

void ParserXML::
on_warning(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_warning(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_warning(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
  }
}

void ParserXML::
on_error(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_error(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_error(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
  }
}

void ParserXML::
on_fatal_error(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_fatal_error(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_characters(): Exception caught while converting value for std::cout: " << ex.what() << std::endl;
  }
}

#endif